www.gusucode.com > VC++ 高仿QQ2008好友界面源码程序 > VC++ 高仿QQ2008好友界面源码程序/code/MyICQ/BmpBtn.cpp

    // BmpBtn.cpp : implementation file
// Download by http://www.NewXing.com

#include "stdafx.h"
#include "MyICQ.h"
#include "BmpBtn.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBmpBtn

CBmpBtn::CBmpBtn()
{
	m_bFirstDC=TRUE;
	m_dwState=NORMAL;
	m_bMouseOver=FALSE;
	m_hCurHandle=AfxGetApp()->LoadCursor(IDC_HANDLE);
	m_clrMask=NULL;
	m_hIcon=NULL;
	m_crBorder=RGB( 15,107,148);
	m_crFg=NULL;
	m_crBk=NULL;
}

CBmpBtn::~CBmpBtn()
{
}


BEGIN_MESSAGE_MAP(CBmpBtn, CButton)
	//{{AFX_MSG_MAP(CBmpBtn)
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBmpBtn message handlers

void CBmpBtn::TransparentBlt1(CDC *pDC, CBitmap &Image, CRect &rect, COLORREF rgbMask)
{
	CDC ImageDC,MaskDC;
	
	CBitmap *pOldImage;
	CBitmap maskBitmap,*pOldMaskDCBitmap ;
	
//	Image.LoadBitmap(nBmp);
	ImageDC.CreateCompatibleDC(pDC);
	pOldImage=ImageDC.SelectObject(&Image);
	
	MaskDC.CreateCompatibleDC(pDC);
	maskBitmap.CreateBitmap( rect.Width(), rect.Height(), 1, 1, NULL );
	pOldMaskDCBitmap = MaskDC.SelectObject( &maskBitmap );
	
	ImageDC.SetBkColor(rgbMask);
	MaskDC.BitBlt( 0, 0, rect.Width(), rect.Height(), &ImageDC, 0, 0, SRCCOPY );
	
	ImageDC.SetBkColor(RGB(0,0,0));
	ImageDC.SetTextColor(RGB(255,255,255));
	ImageDC.BitBlt(0, 0, rect.Width(), rect.Height(), &MaskDC, 0, 0, SRCAND);
	
	pDC->BitBlt(rect.left,rect.top,rect.Width(), rect.Height(), &MaskDC, 0, 0, SRCAND);
	pDC->BitBlt(rect.left,rect.top,rect.Width(), rect.Height(), &ImageDC, 0, 0,SRCPAINT);
	
	MaskDC.SelectObject(pOldMaskDCBitmap);
	ImageDC.SelectObject(pOldImage);

}

BOOL CBmpBtn::Create(LPCTSTR lpszText, DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, UINT nID, DWORD nFlag)
{
	dwStyle|=BS_OWNERDRAW;
	return CButton::Create(lpszText,dwStyle,rect,pParentWnd,nID);
}

void CBmpBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	// TODO: Add your code to draw the specified item
	UINT state=lpDrawItemStruct->itemState;
	
	if(state&ODS_FOCUS)
	{
		if(state&ODS_SELECTED)
		{
			m_dwState=HDOWN;
		}
		else
		{
			if (m_bMouseOver)
			{
				m_dwState=HOVER;
			}
		}
	}
	else
	{
		m_dwState=NORMAL;
	}
	if(state&ODS_DISABLED)
	{
		m_dwState=DISABLE;
	}
	DrawButton();
}

void CBmpBtn::DrawButton()
{
	CClientDC dc(this);
	CDC memDC;memDC.CreateCompatibleDC(&dc);
	CRect rc;GetClientRect(&rc);
	CBitmap bmpComp;bmpComp.CreateCompatibleBitmap(&dc,rc.Width(),rc.Height());
	CBitmap *pBmpOld=memDC.SelectObject(&bmpComp);

	memDC.BitBlt(0,0,rc.Width(),rc.Height(),&m_memDC,0,0,SRCCOPY);
	memDC.SetBkMode(TRANSPARENT);
	CFont *ftOld=memDC.SelectObject(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
//	CFont * oft = (CFont *) pDC->SelectObject(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
	CString strText;GetWindowText(strText);
//	CDC tmpDC;tmpDC.CreateCompatibleDC()
	switch (m_dwState)
	{
	case NORMAL:
		{
			if(m_bmpNormal.GetSafeHandle())
			{
				if(m_clrMask)
					TransparentBlt1(&memDC,m_bmpNormal,rc,m_clrMask);
				else
					memDC.SelectObject(&m_bmpNormal);
			}
			else
			{
				if(m_hIcon)
				{
					::DrawIconEx(memDC,2,2,m_hIcon,m_cxy,m_cxy,0,NULL,DI_NORMAL);
 					CRect rc1;rc1.CopyRect(rc);
 					rc1.left=m_cxy+2*2;
					rc1.top+=2;
					memDC.DrawText(strText,rc1,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
				}
				else
				{
					if(m_crFg)
						memDC.SetTextColor(m_crFg);
					memDC.DrawText(strText,strlen(strText),rc,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
				}
			}
		}
		break;
	case HOVER:
		{
			if(m_bmpHover.GetSafeHandle())
			{
				if(m_clrMask)
					TransparentBlt1(&memDC,m_bmpHover,rc,m_clrMask);
				else
					memDC.SelectObject(&m_bmpHover);
			}
			else
			{
				if(m_hIcon)
				{
					if(strlen(strText))
						memDC.Draw3dRect(rc,m_crBorder,m_crBorder);
					::DrawIconEx(memDC,2,2,m_hIcon,m_cxy,m_cxy,0,NULL,DI_NORMAL);
 					CRect rc1;rc1.CopyRect(rc);
					rc1.left=m_cxy+2*2;
					rc1.top+=2;
					memDC.DrawText(strText,rc1,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
 				}
				else
				{
					if(m_crFg)
						memDC.SetTextColor(m_crFg);
					memDC.Draw3dRect(rc,m_crBorder,m_crBorder);
					memDC.DrawText(strText,rc,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
				}
			}
		}
		break;
	case HDOWN:
		{
			if(m_bmpHdown.GetSafeHandle())
			{
				if(m_clrMask)
					TransparentBlt1(&memDC,m_bmpHdown,rc,m_clrMask);
				else
					memDC.SelectObject(&m_bmpHdown);
			}
			else
			{
				if(m_hIcon)
				{	if(strlen(strText))
						memDC.Draw3dRect(rc,m_crBorder,m_crBorder);
					::DrawIconEx(memDC,3,3,m_hIcon,m_cxy,m_cxy,0,NULL,DI_NORMAL);

					CRect rc1;rc1.CopyRect(rc);
					rc1.left=m_cxy+2*2+1;
					rc1.top+=2+2;
					memDC.DrawText(strText,rc1,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
				}
				else
				{
					if(m_crFg)
						memDC.SetTextColor(m_crFg);
					memDC.Draw3dRect(rc,m_crBorder,m_crBorder);
					rc.left+=2;rc.top=2;
					memDC.DrawText(strText,rc,DT_SINGLELINE|DT_VCENTER|DT_LEFT);
				}
			}
		}
		break;
	case DISABLE:
		{
			/*::SetCursor(AfxGetApp()->)*/
		}
		break;
	}

	dc.BitBlt(0,0,rc.Width(),rc.Height(),&memDC,0,0,SRCCOPY);
	memDC.SelectObject(pBmpOld);
	pBmpOld->DeleteObject();
}

void CBmpBtn::PreSubclassWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
// 	ModifyStyle(NULL,BS_OWNERDRAW);
// 	Invalidate();
	CButton::PreSubclassWindow();
}

BOOL CBmpBtn::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bFirstDC)
	{
		m_memDC.CreateCompatibleDC(pDC);
		CRect rc;GetClientRect(&rc);
		CBitmap bmpBack;bmpBack.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
		CBitmap *bmpOld=m_memDC.SelectObject(&bmpBack);
		m_memDC.BitBlt(0,0,rc.Width(),rc.Height(),pDC,0,0,SRCCOPY);
		m_memDC.SelectObject(&bmpBack);
		m_bFirstDC=FALSE;
	}

	return TRUE;
}

void CBmpBtn::SetBmp(UINT nBmpNormal, UINT nBmpHover, UINT nBmpHdown,COLORREF clrMask)
{
	m_clrMask=clrMask;
	if(nBmpNormal)
		m_bmpNormal.LoadBitmap(nBmpNormal);
	if(nBmpHover)
		m_bmpHover.LoadBitmap(nBmpHover);
	if(nBmpHdown)
		m_bmpHdown.LoadBitmap(nBmpHdown);
}

void CBmpBtn::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	m_bMouseOver=TRUE;
	m_dwState=HOVER;
//	Invalidate();
	DrawButton();
	SetTimer(1,10,NULL);
	CButton::OnMouseMove(nFlags, point);
}

BOOL CBmpBtn::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
//	::SetCursor(AfxGetApp()->LoadCursor(IDC_HANDLE));
	::SetCursor(m_hCurHandle);
	return TRUE;
//	return CButton::OnSetCursor(pWnd, nHitTest, message);
}

void CBmpBtn::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	CPoint pt(GetMessagePos());
	ScreenToClient(&pt);
	CRect rc;GetClientRect(&rc);

	if(rc.PtInRect(pt))
	{
	//	m_dwState=HOVER;
	}
	else
	{
		m_dwState=NORMAL;
		m_bMouseOver=false;
		KillTimer(1);
	}
	DrawButton();
	CButton::OnTimer(nIDEvent);
}

void CBmpBtn::SetIcon(UINT nIcon,int ncxy)
{
	m_hIcon=AfxGetApp()->LoadIcon(nIcon);
	m_cxy=ncxy;
	//GetSize
// 	ICONINFO IconInfo;
// 	;;GetIconInfo(m_hIcon,&IconInfo);
// 	HBITMAP hBm;
// 	BITMAP	bm;
// 	hBm=IconInfo.hbmColor;
// 	::GetObject(hBm,sizeof(bm),&bm);
}